package com.example.springboottestgit.service;

import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONObject;
import com.example.springboottestgit.bean.BusinessException;
import com.example.springboottestgit.bean.CommonException;
import com.example.springboottestgit.bean.dto.LawDTO;
import com.example.springboottestgit.bean.dto.PurchasePackageDTO;
import com.example.springboottestgit.bean.vo.FileVO;
import com.example.springboottestgit.bean.vo.InputVO;
import com.example.springboottestgit.bean.vo.LawVO;
import com.example.springboottestgit.bean.vo.OutputVO;
import com.example.springboottestgit.enums.ExceptionCodeEnum;
import com.example.springboottestgit.enums.LawQuestionEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @description:招标文件-法律法规
 * @author: ZZZ
 */
@Slf4j
@Service
public class InviteTenderService {

    @Value("${law.mode.url}")
    private String lawModeUrl;

    private Map<Long, FileVO> map = new HashMap<>();
    private Map<String, String> question = new HashMap<>();

    public void clear() {
        map.clear();
        question.clear();
    }

    private boolean recordEnable = false;

    public void updateRecordEnable(int n) {
        if (n == 1024) {
            recordEnable = true;
        } else {
            recordEnable = false;
            question.clear();
        }

    }

    public void save(long id, String fileName) {
        List<LawVO> list = new ArrayList<>();
        FileVO<LawVO> vo = new FileVO();
        vo.setId(id);
        vo.setFileName(fileName);
        vo.setStatus(0);
        vo.setList(list);
        vo.setUploadTime(getDataTime());
        //vo.setTechnologyList(technologyList);

        map.put(id, vo);
    }

    public String getDataTime() {
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String now = dtf.format(LocalDateTime.now());
        return now;
    }

    public void updateStatus(Long id, int status) {
        FileVO fileVO = map.get(id);
        if (fileVO != null) {
            fileVO.setStatus(2);
        }
    }

    public String inviteTenderName(long id) {
        FileVO fileVO = map.get(id);
        if (fileVO == null) {
            log.error("招标文件不存在");
            throw new CommonException(ExceptionCodeEnum.QUERY_NO_RESULT.code, "招标文件不存在");
        }
        String inviteTenderName = fileVO.getFileName();
        String prefixName = inviteTenderName.substring(0, inviteTenderName.lastIndexOf("."));
        return prefixName;
    }


    public List<FileVO> lawQuery(List<Long> ids) {

        List<FileVO> list = new ArrayList<>();
        for (Long id : ids) {
            FileVO fileVO = map.get(id);
            if (!StringUtils.isEmpty(fileVO)) {
                list.add(fileVO);
            }
        }
        return list;
    }

    @Async("myAsync")
    public void question(long id, String jsonStr) {
        try {
            LocalDateTime s = LocalDateTime.now();

            jsonStr = jsonStr.replace(" ", "").replace("（元）", "");
            LawDTO dto = JSONObject.parseObject(jsonStr, LawDTO.class);

            log.info("========招标解析文件内容问答==========");
            Thread.sleep(2000);

            purchaseMode(id, dto);
            margin(id, dto);
            AddPurchaseAmount(id, dto);
            ContractTimeLimit(id, dto);
            TbExpireService(id, dto);
            TbNoticeTerm(id, dto);
            ZbQueryPeriod(id, dto);
            failTenderBackMargin(id, dto);
            winTenderBackMargin(id, dto);
            withdrawTenderBackMargin(id, dto);

            inviteTendersChangeNotice(id, dto);
            winTenderNotice(id, dto);

            placementDisabledPeopleProportion(id, dto);
            promiseMargin(id, dto);
            qualificationReview(id, dto);

            //完成
            map.get(id).setStatus(1);

            LocalDateTime e = LocalDateTime.now();
            Duration between = Duration.between(s, e);
            log.info("{} 法律法规模型问答耗时 {} 秒", inviteTenderName(id), between.getSeconds());
        } catch (Exception e) {
            //失败
            map.get(id).setStatus(2);
            throw new BusinessException("001001", "招标解析文件内容问答过程失败");
        }

    }

    @Async("myAsync")
    public void question2(long id, String jsonStr) throws InterruptedException {
        //jsonStr = jsonStr.replace("（", "").replace("）", "").replace(" ", "").replace("。", "");
        log.info("========投标解析文件内容问答==========");
        Thread.sleep(3000);
        String[] split = jsonStr.split(",");
        for (String question : split) {
            String text = askLawQuestion(question);
            LawVO vo = new LawVO();
            boolean result = askLawResult(text);
            vo.setContent(question);
            vo.setResult(result);
            vo.setOutput(text);
            map.get(id).getList().add(vo);
        }
    }


    public void AddPurchaseAmount(long id, LawDTO dto) {
        LawVO vo = new LawVO();
        if (!StringUtils.hasText(dto.getAddPurchaseAmount())) {
            vo.setResult(false);
            vo.setContent(LawQuestionEnum.ADD_PURCHASE_AMOUNT.getTitle().replace("#", "无"));
            map.get(id).getList().add(vo);
            return;
        }
        Pattern pattern = Pattern.compile("10+.\\d+%");
        Matcher matcher = pattern.matcher(dto.getAddPurchaseAmount());
        if (matcher.find(0)) {
            String group = matcher.group(0).replace("%", "");
            if (Double.parseDouble(group) > 10.0) {
                vo.setResult(false);
                vo.setContent(LawQuestionEnum.ADD_PURCHASE_AMOUNT.getTitle().replace("#", dto.getAddPurchaseAmount()));
                map.get(id).getList().add(vo);
                return;
            }
        }

        String question = LawQuestionEnum.ADD_PURCHASE_AMOUNT.getQuestion().replace("#", dto.getAddPurchaseAmount());
        String text = askLawQuestion(question);
        boolean result = askLawResult(text);
        vo.setContent(LawQuestionEnum.ADD_PURCHASE_AMOUNT.getTitle().replace("#", dto.getAddPurchaseAmount()));
        vo.setResult(result);
        vo.setOutput(text);
        map.get(id).getList().add(vo);
    }

    public void ContractTimeLimit(long id, LawDTO dto) {
        LawVO vo = new LawVO();
        if (!StringUtils.hasText(dto.getContractTimeLimit())) {
            vo.setResult(false);
            vo.setContent(LawQuestionEnum.Contract_Time_Limit.getTitle().replace("#", "无"));
            map.get(id).getList().add(vo);
            return;
        }
        dto.setContractTimeLimit(dto.getContractTimeLimit().replace("\"", ""));
        String question = LawQuestionEnum.Contract_Time_Limit.getQuestion().replace("#", dto.getContractTimeLimit());
        String text = askLawQuestion(question);
        boolean result = askLawResult(text);
        vo.setContent(LawQuestionEnum.Contract_Time_Limit.getTitle().replace("#", dto.getContractTimeLimit()));
        vo.setResult(result);
        vo.setOutput(text);
        map.get(id).getList().add(vo);
    }

    public void purchaseMode(long id, LawDTO dto) {
        LawVO vo = new LawVO();
        String purchaseMode = dto.getPurchaseMode();
        if (!StringUtils.hasText(purchaseMode)) {
            vo.setResult(false);
            vo.setContent(LawQuestionEnum.PURCHASE_MODE.getTitle().replace("#", "无"));
            map.get(id).getList().add(vo);
            return;
        }

        if (purchaseMode.contains("不") || purchaseMode.contains("非")) {
            vo.setResult(false);
        } else {
            boolean result = purchaseMode.contains("公开招标") || purchaseMode.contains("邀请招标") || purchaseMode.contains("竞争性谈判") || purchaseMode.contains("单一来源采购") || purchaseMode.contains("询价");
            vo.setResult(result);
        }
        vo.setContent(LawQuestionEnum.PURCHASE_MODE.getTitle().replace("#", purchaseMode));
        vo.setOutput(LawQuestionEnum.PURCHASE_MODE.getLaw());
        map.get(id).getList().add(vo);

    }

    public void margin(long id, LawDTO dto) {
        List<PurchasePackageDTO> purchasePackageList = dto.getMarginList();
        for (PurchasePackageDTO purchasePackageDTO : purchasePackageList) {

            Boolean result = purchasePackageDTO.getMarginAmount() > purchasePackageDTO.getBudgetAmount() * 0.02 ? false : true;
            String answer = result == true ? "未超过" : "超过";

//            String c = "等于";
//            if (purchasePackageDTO.getMarginAmount() < purchasePackageDTO.getBudgetAmount() * 0.02) {
//                c = "小于";
//            }
//            if (purchasePackageDTO.getMarginAmount() > purchasePackageDTO.getBudgetAmount() * 0.02) {
//                c = "大于";
//            }
            //String output = "#。根据《中华人民共和国政府采购法实施条例》规定，投标保证金不得超过采购项目预算金额的2%。因为投标保证金金额b元 c 采购项目预算金额的2% = y元 × 2% = y元 × 0.02 = z元，所以投标保证金b元#采购项目预算金额y的2%（z元）。";
            //output = output.replace("#", answer).replace("c", c).replace("b", String.valueOf(purchasePackageDTO.getMarginAmount())).replace("y", String.valueOf(purchasePackageDTO.getBudgetAmount())).replace("z", String.valueOf(purchasePackageDTO.getBudgetAmount() * 0.02));

            LawVO vo = new LawVO();
            String content = purchasePackageDTO.getName() + "：" + LawQuestionEnum.MARGIN.getTitle();
            content = content.replace("x", purchasePackageDTO.getMarginAmount() + "").replace("y", purchasePackageDTO.getBudgetAmount() + "").replace("#", answer).replace("z", String.valueOf(purchasePackageDTO.getBudgetAmount() * 0.02));
            vo.setContent(content);
            //vo.setInput(purchasePackageDTO.getName() + " 预算金额：" + purchasePackageDTO.getBudgetAmount() + " 保证金金额：" + purchasePackageDTO.getMarginAmount());
            //vo.setQuestion("");
            vo.setResult(result);
            //vo.setAnswer(answer);
            //vo.setOutput(output);

            FileVO fileVO = map.get(id);
            fileVO.getList().add(vo);
        }
    }


    public void TbExpireService(long id, LawDTO dto) {
        LawVO vo = new LawVO();
        if (!StringUtils.hasText(dto.getTbExpire())) {
            vo.setResult(false);
            vo.setContent(LawQuestionEnum.TB_EXPIRE.getTitle().replace("#", "无"));
            map.get(id).getList().add(vo);
            return;
        }
        dto.setTbExpire(dto.getTbExpire().replace("\"", ""));
        String question = LawQuestionEnum.TB_EXPIRE.getQuestion().replace("#", dto.getTbExpire());
        String text = askLawQuestion(question);
        //boolean result = text.startsWith("是的") || text.startsWith("符合");
        boolean result = askLawResult(text);
        vo.setContent(LawQuestionEnum.TB_EXPIRE.getTitle().replace("#", dto.getTbExpire()));
        vo.setResult(result);
        vo.setOutput(text);
        map.get(id).getList().add(vo);
    }

    public void TbNoticeTerm(long id, LawDTO dto) {
        LawVO vo = new LawVO();
        if (!StringUtils.hasText(dto.getTbNoticeTerm())) {
            vo.setResult(false);
            vo.setContent(LawQuestionEnum.TB_NOTICE_TERM.getTitle().replace("#", "无"));
            map.get(id).getList().add(vo);
            return;
        }
        String question = LawQuestionEnum.TB_NOTICE_TERM.getQuestion().replace("#", dto.getTbNoticeTerm());
        String text = askLawQuestion(question);
        boolean result = askLawResult(text);
        vo.setContent(LawQuestionEnum.TB_NOTICE_TERM.getTitle().replace("#", dto.getTbNoticeTerm()));
        vo.setResult(result);
        vo.setOutput(text);
        map.get(id).getList().add(vo);
    }

    public void ZbQueryPeriod(long id, LawDTO dto) {
        LawVO vo = new LawVO();
        if (!StringUtils.hasText(dto.getZbQueryPeriod())) {
            vo.setResult(false);
            vo.setContent(LawQuestionEnum.ZB_QUERY_PERIOD.getTitle().replace("#", "无"));
            map.get(id).getList().add(vo);
            return;
        }
        String question = LawQuestionEnum.ZB_QUERY_PERIOD.getQuestion().replace("#", dto.getZbQueryPeriod());
        String text = askLawQuestion(question);
        boolean result = askLawResult(text);
        vo.setContent(LawQuestionEnum.ZB_QUERY_PERIOD.getTitle().replace("#", dto.getZbQueryPeriod()));
        vo.setResult(result);
        vo.setOutput(text);
        map.get(id).getList().add(vo);
    }

    public void failTenderBackMargin(long id, LawDTO dto) {
        LawVO vo = new LawVO();
        if (!StringUtils.hasText(dto.getFailTenderBackMargin())) {
            vo.setResult(false);
            vo.setContent(LawQuestionEnum.FAIL_TENDER_BACK_MARGIN.getTitle().replace("#", "无"));
            map.get(id).getList().add(vo);
            return;
        }
        String question = dto.getFailTenderBackMargin() + "是否符合法律法规";
        String text = askLawQuestion(question);
        boolean result = askLawResult(text);
        vo.setContent(LawQuestionEnum.FAIL_TENDER_BACK_MARGIN.getTitle().replace("#", dto.getFailTenderBackMargin()));
        vo.setResult(result);
        vo.setOutput(text);
        map.get(id).getList().add(vo);
    }

    public void winTenderBackMargin(long id, LawDTO dto) {
        LawVO vo = new LawVO();
        if (!StringUtils.hasText(dto.getWinTenderBackMargin())) {
            vo.setResult(false);
            vo.setContent(LawQuestionEnum.WIN_TENDER_BACK_MARGIN.getTitle().replace("#", "无"));
            map.get(id).getList().add(vo);
            return;
        }
        String question = dto.getWinTenderBackMargin() + "是否符合法律法规";
        String text = askLawQuestion(question);
        boolean result = askLawResult(text);
        vo.setContent(LawQuestionEnum.WIN_TENDER_BACK_MARGIN.getTitle().replace("#", dto.getWinTenderBackMargin()));
        vo.setResult(result);
        vo.setOutput(text);
        map.get(id).getList().add(vo);
    }

    public void withdrawTenderBackMargin(long id, LawDTO dto) {
        LawVO vo = new LawVO();
        if (!StringUtils.hasText(dto.getWithdrawTenderBackMargin())) {
            vo.setResult(false);
            vo.setContent(LawQuestionEnum.Withdraw_TENDER_BACK_MARGIN.getTitle().replace("#", "无"));
            map.get(id).getList().add(vo);
            return;
        }
        String question = dto.getWithdrawTenderBackMargin() + "是否符合法律法规";
        String text = askLawQuestion(question);
        boolean result = askLawResult(text);
        vo.setContent(LawQuestionEnum.Withdraw_TENDER_BACK_MARGIN.getTitle().replace("#", dto.getWithdrawTenderBackMargin()));
        vo.setResult(result);
        vo.setOutput(text);
        map.get(id).getList().add(vo);

    }


    public void inviteTendersChangeNotice(long id, LawDTO dto) {
        LawVO vo = new LawVO();
        if (!StringUtils.hasText(dto.getInviteTendersChangeNotice())) {
            vo.setResult(false);
            vo.setContent(LawQuestionEnum.Invite_Tenders_Change_Notice.getTitle().replace("#", "无"));
            map.get(id).getList().add(vo);
            return;
        }
        String question = dto.getInviteTendersChangeNotice().replace("。", "，") + "这句话是否符合法律法规";
        String text = askLawQuestion(question);
        boolean result = askLawResult(text);
        vo.setContent(LawQuestionEnum.Invite_Tenders_Change_Notice.getTitle().replace("#", dto.getInviteTendersChangeNotice()));
        vo.setResult(result);
        vo.setOutput(text);
        map.get(id).getList().add(vo);

    }

    public void qualificationReview(long id, LawDTO dto) {
        List<PurchasePackageDTO> qualificationReview = dto.getQualificationReview();
        if (qualificationReview == null || qualificationReview.size() < 1) {
            LawVO vo = new LawVO();
            vo.setResult(false);
            vo.setContent("资格及资信证明文件：无");
            map.get(id).getList().add(vo);
            return;
        }
        Map<String, String> repeat = new HashMap<>();
        for (PurchasePackageDTO purchasePackageDTO : qualificationReview) {
            String name = purchasePackageDTO.getName();
            String content = purchasePackageDTO.getContent();
            String[] split = content.split(";");
            for (String certificate : split) {
                String text = "";
                LawVO vo = new LawVO();
                if (repeat.containsKey(certificate)) {
                    text = repeat.get(certificate);
                } else {
                    String question = certificate + "是否可以作为投标人的资格及资信证明文件";
                    text = askLawQuestion(question);
                    repeat.put(certificate, text);
                }
                boolean result = askLawResult(text);
                vo.setContent(name + " 资格及资信证明文件：" + certificate);
                vo.setResult(result);
                vo.setOutput(text);
                map.get(id).getList().add(vo);
            }
        }
    }

    public void promiseMargin(long id, LawDTO dto) {
        List<PurchasePackageDTO> promiseMargin = dto.getPromiseMargin();
        if (promiseMargin == null || promiseMargin.size() < 1) {
            LawVO vo = new LawVO();
            vo.setResult(false);
            vo.setContent("履约保证金：无");
            map.get(id).getList().add(vo);
            return;
        }
        for (PurchasePackageDTO purchasePackageDTO : promiseMargin) {
            String name = purchasePackageDTO.getName();
            String content = purchasePackageDTO.getContent();
            content = content.replace(",", "");

            LawVO vo = new LawVO();
            Pattern pattern = Pattern.compile("10+.\\d+%");
            Matcher matcher = pattern.matcher(content);
            if (matcher.find(0)) {
                String group = matcher.group(0).replace("%", "");
                if (Double.parseDouble(group) > 10.0) {
                    vo.setResult(false);
                    vo.setContent(name + " 履约保证金：" + content);
                    map.get(id).getList().add(vo);
                    return;
                }
            }

            String question = LawQuestionEnum.Promise_Margin.getQuestion().replace("#", content);

            if (content.contains("不用缴纳") || content.contains("不缴纳") || content.contains("无需缴纳")) {
                vo.setResult(true);
            } else {
                String text = askLawQuestion(question);
                boolean result = askLawResult(text);
                vo.setResult(result);
                vo.setOutput(text);
            }
            vo.setContent(name + " 履约保证金：" + content);
            map.get(id).getList().add(vo);

        }

    }

    public void winTenderNotice(long id, LawDTO dto) {
        LawVO vo = new LawVO();
        if (!StringUtils.hasText(dto.getWinTenderNotice())) {
            vo.setResult(false);
            vo.setContent(LawQuestionEnum.Win_Tender_Notice.getTitle().replace("#", "无"));
            map.get(id).getList().add(vo);
            return;
        }
        String question = dto.getWinTenderNotice() + "是否符合法律法规";
        String text = askLawQuestion(question);
        boolean result = askLawResult(text);
        vo.setContent(LawQuestionEnum.Win_Tender_Notice.getTitle().replace("#", dto.getWinTenderNotice()));
        vo.setResult(result);
        vo.setOutput(text);
        map.get(id).getList().add(vo);
    }


    public void placementDisabledPeopleProportion(long id, LawDTO dto) {
        LawVO vo = new LawVO();
        if (!StringUtils.hasText(dto.getPlacementDisabledPeopleProportion())) {
            vo.setResult(false);
            vo.setContent(LawQuestionEnum.Placement_Disabled_People_Proportion.getTitle().replace("#", "无"));
            map.get(id).getList().add(vo);
            return;
        }
        if (dto.getPlacementDisabledPeopleProportion().indexOf("，") > -1) {
            dto.setPlacementDisabledPeopleProportion(dto.getPlacementDisabledPeopleProportion().substring(0, dto.getPlacementDisabledPeopleProportion().indexOf("，")));
        }
        dto.setPlacementDisabledPeopleProportion(dto.getPlacementDisabledPeopleProportion().replace("（含25%）", ""));
        String question = "安置的残疾人" + dto.getPlacementDisabledPeopleProportion() + "是否符合法律法规";
        String text = askLawQuestion(question);
        boolean result = askLawResult(text);
        vo.setContent(LawQuestionEnum.Placement_Disabled_People_Proportion.getTitle().replace("#", dto.getPlacementDisabledPeopleProportion()));
        vo.setResult(result);
        vo.setOutput(text);
        map.get(id).getList().add(vo);

    }


    public String askLawQuestion(String question) {

        String url = lawModeUrl;
        InputVO vo = new InputVO();
        //10.0%   10%
        question = question.replaceAll("\\.\\d+%", "%");
        vo.setPrompt(question);
        String param = JSONObject.toJSONString(vo);
        log.info("法律法规提问：" + question);


        String result = null;
        try {
            result = HttpUtil.createPost(url)
                    //这个请求头.header是自己项目需要加的，可以省略
                    .header("Content-Type", "application/json")
                    //这两个请求头是项目需要加的，可以省略
                    //传输参数
                    .body(param).execute().body();
        } catch (Exception e) {
            log.error("法律法规模型接口调用失败", e);
            throw new BusinessException(ExceptionCodeEnum.INTERFACE_CALL_FAIL.code, "法律法规模型接口调用失败");
        }
        OutputVO out = JSONObject.parseObject(result, OutputVO.class);
        String text = out.getChoices().get(0).getText();
        log.info("法律法规回答：" + text);
        System.out.println();
        return text;
    }

    public boolean askLawResult(String text) {
        if (text.length() > 50) {
            text = text.substring(0, 50);
        }
        boolean result = text.contains("不是的") || text.contains("不符合") || text.contains("不可以") ? false : true;
        return result;
    }
}
